//给定两个整数数组 inorder 和 postorder ，其中 inorder 是二叉树的中序遍历， postorder 是同一棵树的后序遍历，请你构造并
//返回这颗 二叉树 。 
//
// 
//
// 示例 1: 
//
// 
//输入：inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
//输出：[3,9,20,null,null,15,7]
// 
//
// 示例 2: 
//
// 
//输入：inorder = [-1], postorder = [-1]
//输出：[-1]
// 
//
// 
//
// 提示: 
//
// 
// 1 <= inorder.length <= 3000 
// postorder.length == inorder.length 
// -3000 <= inorder[i], postorder[i] <= 3000 
// inorder 和 postorder 都由 不同 的值组成 
// postorder 中每一个值都在 inorder 中 
// inorder 保证是树的中序遍历 
// postorder 保证是树的后序遍历 
// 
// Related Topics 树 数组 哈希表 分治 二叉树 👍 851 👎 0


package com.cjl.leetcode.editor.cn;

import java.util.HashMap;
import java.util.Map;

/**
 * [P106]_从中序与后序遍历序列构造二叉树
 * @author cjl
 * @date 2022-10-06 20:04:27
 */
public class P106_ConstructBinaryTreeFromInorderAndPostorderTraversal{
      public static void main(String[] args) {
            //测试代码
           Solution solution = new P106_ConstructBinaryTreeFromInorderAndPostorderTraversal().new Solution();
      }
      //力扣代码
      //leetcode submit region begin(Prohibit modification and deletion)
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    /**
     * 解题思路：
     *  中序遍历：左，中，右
     *  后序遍历：左，右，中
     * @param inorder
     * @param postorder
     * @return
     */
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        for(int i = 0 ; i < inorder.length; i++){
            rootMap.put(inorder[i],i);
        }
        return buildTree(inorder,0, inorder.length -1, postorder, 0, postorder.length -1);
    }

    Map<Integer, Integer> rootMap = new HashMap<>();
    public TreeNode buildTree(int[] inorder, int instart, int inend, int[] postorder, int poststart, int postend){
        if(instart > inend){
            return null;
        }
        TreeNode treeNode = new TreeNode();
        //取出 ignorer中 root节点分界位置
        int i = rootMap.get(postorder[postend]);
        treeNode.val = postorder[postend];
        int leftLength = i - instart;
        treeNode.left = buildTree(inorder,instart,i -1, postorder, poststart, poststart + leftLength -1);
        treeNode.right = buildTree(inorder,i+1,inend, postorder, poststart+leftLength, postend -1);
        return treeNode;
    }
}
//leetcode submit region end(Prohibit modification and deletion)

  }